//
//  XBAudioUploader.m
//  qkd_audio_recorder
//
//  Created by Luoei on 2020/4/18.
//

#import "XBAudioUploader.h"
#import <AliyunOSSiOS/AliyunOSSiOS.h>
#import <AVFoundation/AVFoundation.h>
#import "XBAudioTool.h"

@interface XBAudioUploader()

@property(nonatomic,strong) NSTimer * timer;
/// 上传位置
@property(nonatomic,assign) int64_t  position;

@property (nonatomic,strong) NSLock *lock;

@property(nonatomic,strong) NSString * fileName;
/// 上传中的数据
//@property(nonatomic,strong) NSData * uploadingData;
/// 即将要上传的数据
//@property(nonatomic,strong) NSData * preparedData;
/// 总的数据
@property(nonatomic,strong) NSData * data;

@property(assign) BOOL  uploading;
/// 停止录音
@property(nonatomic,assign) BOOL  stopRecord;

@end

static OSSClient *client;
/// 资源域名
static NSString *resourceDomain;

@implementation XBAudioUploader

-(void)timerAction{
    self.data = [NSData dataWithContentsOfFile:self.path];
    [XBAudioTool log:XBAudioLogLevelVerbose message:[NSString stringWithFormat:@"文件大小：%lu", self.data.length] parameters:nil];
    
    if (self.uploading)return;
    int64_t minLength = 10 * 1024; // 最小10k
    if (self.stopRecord){
        if([[NSFileManager defaultManager] fileExistsAtPath:self.path]){
            AVURLAsset *audioAsset = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:self.path]  options:nil];
            CMTime audioDuration = audioAsset.duration;
            float audioDurationSeconds = CMTimeGetSeconds(audioDuration);
            if (audioDurationSeconds > 0.7){
                NSData * preparedData = [self.data subdataWithRange:NSMakeRange(self.position, self.data.length - self.position)];
                [self uploadWithData:preparedData last:YES];
            }else{
                [XBAudioTool log:XBAudioLogLevelError message:[NSString stringWithFormat:@"录音时间太短：%@ -- %f", self.fileName, audioDurationSeconds] parameters:nil];
                [[NSFileManager defaultManager] removeItemAtPath:self.fileName error:nil];
                if (self.completeBlock){
                    self.completeBlock([NSString stringWithFormat:@"%@%@", resourceDomain, self.fileName], 2);
                }
            }
        }else{
            [XBAudioTool log:XBAudioLogLevelError message:[NSString stringWithFormat:@"录音时间太短：%@", self.fileName] parameters:nil];
            if (self.completeBlock){
                self.completeBlock([NSString stringWithFormat:@"%@%@", resourceDomain, self.fileName], 2);
            }
        }
        
        [self stopTimer];
    }else{
        if (self.data.length < minLength) return;
        int64_t length = self.data.length - self.position;
        if (length < minLength)return;
        NSData * preparedData = [self.data subdataWithRange:NSMakeRange(self.position, length)];
        [self uploadWithData:preparedData last:NO];
    }
}


-(void)start{
    [self stopTimer];
    
    self.stopRecord = NO;
    self.position = 0;
    self.fileName = [self genernalFileName];
    self.timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
}

-(void)stop{
    [XBAudioTool log:XBAudioLogLevelInfo message:[NSString stringWithFormat:@"用户停止：%@", self.fileName] parameters:nil];
    self.stopRecord = YES;
}

-(void)destory{
    [self stopTimer];
}

-(void)stopTimer{
    [XBAudioTool log:XBAudioLogLevelInfo message:[NSString stringWithFormat:@"关闭定时器"] parameters:nil];
    if (self.timer){
        [self.timer invalidate];
        self.timer = nil;
    }
}

+(void)setAliyunOSSClient:(id)_client{
    if ([_client isKindOfClass:OSSClient.class]){
        client = _client;
    }
}

+(void)setResourceDomain:(NSString *)domain{
    resourceDomain = domain;
}


-(void)uploadWithPath:(NSString *)path{
    if (self.uploading)return;
    self.uploading = YES;
    self.position = 0;
    self.stopRecord = YES;
    self.fileName = [self genernalFileName];
    [self uploadWithFilePath:path];
}

-(void)uploadWithFilePath:(NSString *)filePath{
    
    OSSPutObjectRequest *object = [OSSPutObjectRequest new];
    // 必填字段
    object.bucketName = @"qkd";
    object.objectKey = self.fileName;
//    append.appendPosition = self.position; // 指定从何处进行追加
    object.uploadingFileURL = [NSURL fileURLWithPath:filePath];
    
    OSSTask * task = [client putObject:object];
    [task continueWithBlock:^id(OSSTask *task) {
        self.uploading = NO;
        
        if (task.error) {
            [XBAudioTool log:XBAudioLogLevelError message:[NSString stringWithFormat:@"录音|上传管理|失败: %@" , task.error] parameters:nil];
        }
        if (self.stopRecord){
            [XBAudioTool log:XBAudioLogLevelInfo message:[NSString stringWithFormat:@"录音|上传管理|%@|上传完成!", self.fileName] parameters:nil];
           if (self.completeBlock){
               self.completeBlock([NSString stringWithFormat:@"%@%@", resourceDomain, self.fileName], !task.error ? 1 : 3);
           }
        }
        return nil;
    }];
}

-(void)uploadWithData:(NSData *)data last:(BOOL)last{
    if (self.uploading)return;
    self.uploading = YES;
    
    OSSAppendObjectRequest * append = [OSSAppendObjectRequest new];
    // 必填字段
    append.bucketName = @"qkd";
    append.objectKey = self.fileName;
    append.appendPosition = self.position; // 指定从何处进行追加
    append.uploadingData = data;
    
    OSSTask * appendTask = [client appendObject:append];
    [appendTask continueWithBlock:^id(OSSTask *task) {
        self.uploading = NO;
        
        if (!task.error) {
            [XBAudioTool log:XBAudioLogLevelVerbose message:[NSString stringWithFormat:@"录音|上传管理|%@|位置: %lld |大小: %lld |添加成功!", self.fileName, self.position, data.length] parameters:nil];
            OSSAppendObjectResult * result = task.result;
            NSString * etag = result.eTag;
            int64_t nextPosition = result.xOssNextAppendPosition;
            if (!self.stopRecord || !last){
                self.position = nextPosition;
            }
        } else {
            [XBAudioTool log:XBAudioLogLevelError message:[NSString stringWithFormat:@"录音|上传管理|失败: %@" , task.error] parameters:nil];
        }
        if (self.stopRecord && last){
            [XBAudioTool log:XBAudioLogLevelInfo message:[NSString stringWithFormat:@"录音|上传管理|%@|上传完成!", self.fileName] parameters:nil];
           if (self.completeBlock){
               self.completeBlock([NSString stringWithFormat:@"%@%@", resourceDomain, self.fileName], !task.error ? 1 : 3);
           }
        }
        return nil;
    }];
}

-(NSString *)genernalFileName{
    return [@"audio/" stringByAppendingString:[[[[[NSUUID UUID] UUIDString] stringByReplacingOccurrencesOfString:@"-" withString:@""] lowercaseString] stringByAppendingString:@".mp3"]];
}

- (NSLock *)lock
{
    if (_lock == nil)
    {
        _lock = [NSLock new];
    }
    return _lock;
}

@end
